<!DOCTYPE html public '-//W3C//DTD HTML 4.01//EN'
  'http://www.w3.org/TR/html4/strict.dtd'>
<html lang="en">
<head profile="http://www.w3.org/2006/03/hcard">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>CSS shaders</title>
  <link rel="stylesheet" type="text/css" href="default.css">
  <link rel="stylesheet" type="text/css"
        href="https://www.w3.org/StyleSheets/TR/W3C-ED.css">

  <link id="st" href="alternate-spec-style.css" rel="stylesheet" 
      type="text/css" title="additional spec styles">             
        
        <script type="text/javascript" src="style-toggle.js"></script>
  <style type="text/css">
  
  /* Alternate stylesheet fonts are here because in some browsers (Opera 11.5) */
  /* The fonts are not applied if only loaded from the alternate stylesheet    */
  @import url(https://fonts.googleapis.com/css?family=Droid+Serif:700,400,400italic,700italic);
  @import url(https://fonts.googleapis.com/css?family=Droid+Sans+Mono);

  a.toggle {
      position: fixed;
      top: 0.5em;
      right: 0.5em;
  	font-size: smaller;
  	color: gray;
  	opacity: 0.2;
  }

  a.toggle:hover {
      opacity: 1;
      color: #46A4E9;
  }

  div.issue-marker {
      position: absolute;
      width: 20ex;
      margin-left: -26ex;
      padding-left: 1em;
      padding: 5px;
      font-weight: normal;
      font-size: 11px;
      text-align: right;
      background-color: white;
      font-size: 90%;
  }

  div.issue-marker a {
      color: red;
  }
   </style>
</head>

<div id="div-head" class="head">
<!--logo-->

<h1>CSS shaders</h1>

<h2 class="no-num no-toc">23 October 2011</h2>
<dl>
  <dt>Editors:
    <dd class=vcard><span class=fn>Vincent Hardy</span>,
      <span class=org>Adobe Systems,</span>
      <span class=email>vhardy@adobe.com</span></dd>
  <dd class=vcard><span class=fn>Dean Jackson</span>,
    <span class=org>Apple Inc.,</span>
    <span class=email>dino@apple.com</span></dd>
  <dd class=vcard><span class=fn>Erik Dahlström,</span>
      <span class=email>Opera Software ASA</span>, 
      <span class=email>ed@opera.com</span></dd>
</dl>

<!--copyright-->


<hr title="Separator for header">
</div>

<p style="background: #fdd; color: red; font-weight: bold; text-align: center; padding: .5em; border: thick solid red; border-radius: 1em; position: fixed; bottom: 1em; left: 1em; right: 1em;">This specification is not being actively maintained, and should not be used as a guide for implementations.  CSS shaders are an integral part of <a href="https://drafts.fxtf.org/filters/">Filter Effects</a>.  <br>If you have questions or comments on this specification, please send an email to the FX Task Forces's mailing list at <a href="mailto:public-fx@w3.org">public-fx@w3.org</a>.  (Before sending mail for the first time, you have to subscribe at <a href="http://lists.w3.org/Archives/Public/public-fx/">http://lists.w3.org/Archives/Public/public-fx/</a>.)</p>


<h2 class="no-num no-toc" id=abstract>Abstract</h2>

  <p>This document describes a proposed feature called "CSS shaders". 
     CSS shaders are a complement to the <a href="https://drafts.fxtf.org/filters/publish/Filters.html">Filter Effects</a> specification and a solution for its <a href="https://drafts.fxtf.org/filters/publish/Filters.html#feCustomElement">feCustom</a> element. In addition, CSS shaders introduce a notion of <a href="http://en.wikipedia.org/wiki/Vertex_shader">vertex shader</a> into the filter model. The CSS shaders feature is proposed for consideration by the <a href="http://www.w3.org/Graphics/fx/">FX Task Force</a> and could be integrated in the Filter Effects specification or made a separate module. This document is the result of <a href="http://www.w3.org/Graphics/SVG/WG/track/actions/3072">ACTION-3072</a></p>

<h2 class="no-num no-toc" id="contents">Table of contents</h2>

<!--toc-->

<h2 id="intro">
Introduction</h2>

<p>Graphics architectures such as <a href="http://msdn.microsoft.com/en-us/library/bb219679(v=vs.85).aspx">Microsoft's Direct3D</a> or <a href="http://en.wikipedia.org/wiki/OpenGL">OpenGL</a> have a notion of <a href="http://en.wikipedia.org/wiki/Vertex_shader">vertex shaders</a> that operate on point coordinates (vertices) and a notion of <a href="http://en.wikipedia.org/wiki/Pixel_shader">fragment shaders</a> (often called pixel shaders) which operate on pixel color values.</p>

<p>Vertex shaders operate on a mesh of vertices and provide a way to provide a wide variety of distortion effects (such as a curl, wobble, folding or waving effect). Fragment shaders allow per-pixel operations effects
    such as a <a href="http://en.wikipedia.org/wiki/Bloom_(shader_effect)">bloom</a> effect and various image effects (such as blur, glows or edge detection).</p>

<p>When applied to document content such as HTML or SVG elements, shaders can be used in very interesting ways. These 2D elements can conceptually be drawn on a mesh of vertices that can then be processed through a vertex shader for distortion and then to a fragment shader for pixel processing.</p>

<p>This document proposes to bring the expressiveness of vertex and fragment shaders to CSS so that
    all visual content styled with CSS can benefit from these sophisticated effects.</p>

<p>Shaders are particularly interesting in the context of animated transitions and 
    a complement to the <a href="https://drafts.fxtf.org/filters/publish/Filters.html">Filter Effects 1.0</a>, the <a href="">CSS Animations</a>, the <a href="">CSS Transitions</a> and 
    the <a href="">SVG Animations</a> specifications.</p>

<p>A shader is essentially a small program which provides a particular effect (such as a distortion, a blur or a twirl effect) and whose behavior is controlled with input parameters (such as the amount of distortion, blur or twirl).</p>

<p>This document proposes:</p

<ol>
    <li>a model and a CSS syntax to make vertex shaders apply to arbitrary markup content.</li>
    <li>a CSS syntax to make fragment shaders operate with other <a href="https://drafts.fxtf.org/filters/publish/Filters.html#FilterPrimitivesOverview">filter effects primitives</a>.</li>
    <li>a CSS syntax to make fragment shaders to be used with the <a href="https://drafts.fxtf.org/filters/publish/Filters.html#FilterProperty">'filter'</a> property.
    <li>a CSS syntax to pass parameters to fragment and vertex shaders.</li>
    <li>a CSS syntax to control the granularity of the vertex mesh processed by CSS shaders.</li>
    <li>a CSS syntax for defining a filter effect regions (applicable to CSS shaders, but generally
        useful for filter effects).</li>
</ol>


    
<p>Following are a few examples illustrating how shaders could apply to 
    content styled with CSS.</p>
    
    <div class="figure">
        <img src="images/intro-filtered-element.png" width="300" />
        <p class="caption">Element before applying shaders</p>
    </div>

<h3 id="vertext-shader-example">Simple animated vertex shader example</h3>

<p>The following figure shows a simple vertex shader that transforms vertices to create a 'waving' effect.
    The code snippet illustrates how a 'wave.vs' vertex shader is used for the effect and how the effect can 
        be animated when hovering on an element using CSS transitions (see [[CSS3-TRANSITIONS]]).</p>
    <div class="figure">
        <img src="images/intro-example-1.png" width="300"/><br />
        <p class="caption">Element with a vertex shader applied</p>
    </div>

    <div class="example">
    <code class="idl"><pre>
&lt;style&gt;
.waving      {
    <strong>filter: custom(url('wave.vs'), 20 20, phase 0, amplitude 50);</strong>
    transition-property: filter;
    transition-duration: 0.2s;
}

.waving:hover {
    <strong>filter: custom(url('wave.vs'), 20 20, phase 90, amplitude 20);</strong>
}

&lt;/style&gt;

&lt;html&gt;
...
    &lt;div class='waving'&gt;
        &lt;h2&gt;Hello CSS Shaders&lt;/h2&gt;
        ...
    &lt;/div&gt;
...
&lt;/html&gt;</pre></code>
    </div>
    
    <p>The meaning of the different parameters are explained in this document in details:
        <code>url('wave.vs')</code> references the custom vertex shader that computes the 
        waving effect. The <code>20 20</code> parameter controls the <code><a href="#vertex-mesh">vertex mesh</a></code>
        granularity, so that the wave is smooth. Finally, the <code>phase</code> and <code>amplitude</code>
        parameters control the shape and strength of the sinusoidal curve used for the waving effect.</p>
    
<h3 id="combined-shader-filter-example">Combined vertex and fragment shaders example</h3>


<p>The following figure shows a combination of a vertex shader (to give an 'open book' form to the element) and 
    a fragment shader (to give the image an 'old paper' color style, with a subtle shadow around the middle).
    <div class="figure">
        <img src="images/intro-example-2.png" width="300"/><br />
        <p class="caption">Element with both a vertex shader <br />and a fragment shader applied</p>
    </div>

    <div class="example">
    <code class="idl"><pre>
&lt;style&gt;
.old-book-page {
    <strong>filter: grayscale(1.0) 
            custom(url('book.vs') url('old-page-paper.fs'));</strong>
}

&lt;/style&gt;

&lt;html&gt;
...
    &lt;div class='old-book-page'&gt;
        &lt;h2&gt;Hello CSS Shaders&lt;/h2&gt;
        ...
    &lt;/div&gt;
...
&lt;/html&gt;   </pre></code>
    </div>
    
<p>Note how the 'filter' property (defined in the Filter Effects 1.0 specification) is extended with a <code>custom()</code> function and how that function can be combined with one of the existing filter
    functions (such as <code>grayscale()</code> in the above example)</p>

<p>The shading language is discussed in a later <a href="#shader-language">section</a>.</p>
    
<p>Each shader defines its own set of parameters. Typically, different shaders will have different parameters with different types. For example, a 'box-blur' shader could have a 'box-size' parameter.</p>

<p>The proposal allows an arbitrary number of parameters for shaders</p>

<h3 id="webgl-and-filter-effects">Relation to WebGL and Filter Effects</h3>

<h4>WebGL</h4>

<p><a href="http://www.khronos.org/registry/webgl/specs/latest/">WebGL</a> provides an implementation for the HTML5 <a href="http://dev.w3.org/html5/spec/the-canvas-element.html">canvas</a> element. WebGL offers a 3D context for canvas and, within that context, fragment shaders are available (and so are vertex shaders and all the other 3D features WebGL has to offer). WebGL operates within the bounds of the canvas for which it provides a context for full 3D features. By contrast, CSS shaders provide a way to apply arbitrary vertex and fragment shaders to arbitrary Web content.</p>

<h4>Filter Effects</h4>

<p>The <a href="https://drafts.fxtf.org/filters/publish/Filters.html">Filter Effects</a> specification offers a way to apply a finite set of filter primitives for arbitrary Web content. For each primitive, there is a CSS syntax to configure the primitive effects. For example, there is a parameter to specify the strength of the <code>sepia()</code> filter primitive. CSS shaders provide an extensibility mechanism to Filter Effects by allowing an author to reference a custom shader effect and configure it with an arbitrary set of parameters.</p>

<p>In addition, CSS shaders bring the ability to transform the geometry of document elements in an arbitrary way by allowing vertex shaders to apply to the elements's box (generated box in HTML, object bounding box in SVG).</p>

<h2 id="shader-model">Processing Model</h2>

<p>This section illustrates the CSS shader processing model as it applies to an element whose unfiltered rendering is shown in figure 1.</p>

<h3 id="key-concepts">Key concepts</h3>

<dl>
    <dt id='source-texture'>source texture</dt>
    <dd>The source texture is created by rendering the filtered element into an offscreen image. The offscreen size and 
        position (relative to the target element's box [see <a href='#targetBox'><code>targetBox</code></a>]) is controlled by the 
        filter region.
        <div class="figure">
            <img src="images/shader-concepts-source-texture.png" width="300" />
            <p class="caption">Source texture created by rendering<br />the element offscreen and adding filter primitive margins</p>
        </div>
        When a CSS shader is used in a filter graph (with an <code>feCustom</code> filter primitive),
        the source texture is the output of the <code>feCustom</code>'s input (the <code>'in'</code> 
        attribute).
        <br />
        Note that applying a 'filter' to an element creates a new pseudo-stacking context, 
        as <a href="https://drafts.fxtf.org/filters/publish/Filters.html#filters-in-css">defined in the Filter Effects specification</a>.
        </dd>
        
    <dt id="filter-region">filter region</dt>
    <dd>The filter region defines the size and position of the source texture. In the previous figure, the 
        blue border represents the filter region. The filter region is the intersection of the 
        <a href="https://drafts.fxtf.org/filters/publish/Filters.html#FilterEffectsRegion">filter effect region</a> and the <a href="https://drafts.fxtf.org/filters/publish/Filters.html#FilterPrimitiveSubRegion">filter primitive subregion</a></dd>
    <dt id="vertex-mesh">vertex mesh</dt>
    <dd>The vertex mesh defines the geometry that is processed by the vertex shader. By default,
        the extent of the 
        vertex mesh is the same as the <a href="#filter-region">filter region</a>. In the following figure, the red markers represent the default
        vertices in the default vertex mesh. The diagonal line illustrate how the vertices define two triangles.
        
        <div class="figure">
            <img src="images/shader-concepts-default-mesh.png" width="300" />
            <p class="caption">The default vertex mesh and its default vertices</p>
        </div>
        
        It is possible to define a finer vertex mesh (see the <a href='#custom-function'><code>custom()</code></a> function and the <code><a href="feCustomVertexMeshAttribute">'vertexMesh'</a></code> attribute).
        
        <div class="figure">
            <img src="images/shader-concepts-finer-mesh.png" width="300" />
            <p class="caption">A finer, custom vertex mesh</p>
        </div>

        <p>The &lt;box&gt; parameter in the <code>vertexMesh</code> attribute value 
        controls if the mesh aligns with the filter region box, the content box,
        the padding box or the border box.</p>
        
        <p id="mesh-box">The <em>mesh-box</em> is the box the mesh aligns with.</p>
        
        <p>The shader mesh can either be a set of connected triangles, or a set of disconnected
            triangles. This option is controlled by the <a href='#detached'>detached</a> parameter.</p>
        </dd>
</dl>

<h3 id="model">Model</h3>

<p>A CSS shader defines a custom filter primitive. The following figure illustrates its model.</p>

<div class="figure">
    <img src="images/shader-model.png" width="800" />
    <p class="caption">The CSS shader processing model</p>
</div>

<p>The CSS shader is defined by a <code>custom()</code> function or an <code>&lt;feCustom&gt;</code> filter primitive. As explained later, a <code>custom()</code> function is a shorthand for defining 
    a <code>&lt;filter&gt;</code> element with a single <code>&lt;feCustom&gt;</code> filter primitive. Therefore, the discussion explains the <code>feCustom</code> model.</p>
    
<p>The input of the <code>feCustom</code> filter primitive is the same as most of the other
    <a href="https://drafts.fxtf.org/filters/publish/Filters.html#FilterPrimitivesOverview">filter primitives</a> and defined by that element's '<code><a href="https://drafts.fxtf.org/filters/publish/Filters.html#CommonAttributes">in</a>'</code> attribute. This is represented as the input of step one in the figure.</p>
    
<p>The input of the <code>&lt;feCustom&gt;</code> filter primitive is used as a texture on a
    vertex mesh. By default, the vertex mesh has the position and size of the filter region and its granularity is controlled by the <a href="#feCustomVertexMeshAttribute"><code>vertexMesh</code></a> attribute
    on <code>&lt;feCustom&gt;</code> (and the <code>&lt;vertex-mesh&gt;</code> parameter in the <code>custom()</code> function). The creation of this vertex mesh with the input texture mapped to the vertices is
    represented in the figure as the output of step 1.</p>
    
<p>The <code>&lt;feCustom&gt;</code> node processes the vertex mesh through the 
    vertex shader in step 2, which produces a set of transformed vertices. This transformed 
    vertices are the output of step 2.</p>
    
<p>During the rasterization step, the <code>&lt;feCustom&gt;</code> primitive invokes the 
    fragment shader for every pixel location inside the vertex mesh to perform per pixel operation 
    and produce the final
    pixel color at that vertex mesh location. This is the output of step 3. Note that the fragment
    shader may be called several time for what corresponds to the same pixel coordinate on the
    output, for example when the vertex mesh folds over itself.</p>
    
<p>Step 4 shows how this rasterized output is the input to the next step in the filter chain (or graph, since <code>&lt;filter&gt;</code> elements can define a graph of filters). If the
    <code>&lt;feCustom&gt;</code> primitive is the last one in the filter chain, then this output is the
    filtered rendering of the element. Otherwise, the output of the primitive becomes the
    input to the next filter primitive using it.</p>
    
<p>The CSS fragment shaders processing model follows the <a href="https://drafts.fxtf.org/filters/publish/Filters.html">Filter Effects 1.0</a>
    specification with regards to <a href="https://drafts.fxtf.org/filters/publish/Filters.html#filters-in-css">how filters apply to HTML</a> and how the <a href="https://drafts.fxtf.org/filters/publish/Filters.html#FilterEffectsRegion">filter region </a> is computed.</p>
    
<div id="about_interactivity" class="note">
    One issue with filter effects is the impact on interactivity. Filters can offset the visual rendering
    of content and affect the way users interact with content. For example, the <a href="https://drafts.fxtf.org/filters/publish/Filters.html#feOffsetElement">feOffset</a>
    element moves the element's rendering by a given offset, which biases the interaction: the end user
    may click on an element and actually hit a different one because of the offset. This issue
    is expected to be more acute with vertex shaders and the working group should consider a general
    solution to this issue that works for both predefined filter effects and custom ones.
</div>
<h2 id="filter-effects">Integration in Filter Effects 1.0</h2>

<p>This document provides a definition for the <a href="#feCustom">feCustom</a> element in the 
    Filter Effects specification. It also defines the 'custom()' function for use in the 'filter' property.</p>
    
<h3 id="custom-function">The <code>custom()</code> function</h3>

<p>The <code>custom()</code> function has the following syntax:</p>

<dl>
    <dt><code>custom(<span class="highlight">&lt;vertex-shader&gt;</span><span class="highlight2">[</span><span class="fade">wsp</span><span class="highlight">&lt;fragment-shader&gt;</span><span class="highlight2">][,</span><span class="highlight">&lt;vertex-mesh&gt;</span><span class="highlight2">][,</span><span class="highlight">&lt;params&gt;</span><span class="highlight2">]</span>)</code></dt>
    <dd><table class="values-desc">
            <tr>
                <td><code>&lt;vertex-shader&gt;</code></td>
                <td><code>&lt;uri&gt; | none</code></td>
            </tr>
            <tr>
                <td><code>&lt;fragment-shader&gt;</code></td>
                <td><code>&lt;uri&gt; | none</code></td>
            </tr>
            <tr>
                <td><code>&lt;vertex-mesh&gt;</code></td>
                <td><code>+&lt;integer&gt;{1,2}[wsp&lt;box&gt;][wsp'detached']</code><br />
                    where: <code>&lt;box&gt; = filter-box | border-box | padding-box | content-box</code></td>
            </tr>
            <tr>
                <td id='#shader-params'><code>&lt;params&gt;</code></td>
                <td>See the <code>&lt;feCustom&gt;</code>'s <a href='#feCustomParamsAttribute'><code>params</code></a> attribute.</td>
            </tr>
        </table>
        </dd>
</dl>
<p>The <code>custom()</code> function is a shorthand for the following filter effect:</p>    

<code class="idl"><pre>
&lt;filter&gt;
    &lt;feCustom vertexShader="<strong>vertex-shader</strong>" 
              fragmentShader="<strong>fragment-shader</strong>" 
              vertexMesh="<strong>vertex-mesh</strong>"
              params="<strong>params</strong>"/&gt;
&lt;/filter&gt;
</pre></code>         

<p>It can be used in combination with other filter shorthands, for example:</p>

<code>filter: sepia(0.5) custom(none url(add.fs), amount 0.2 0.2 0.2);</code>

<div class="note">It might be clearer to name the <code>custom()</code> function 
    the <code>shader()</code> function instead and introduce an <code>feCustomShader</code>
    filter primitive instead of <code>feCustom</code>.</div>
    
<h3 id="feCustom">The <code>feCustom</code> element</h3>

<p>The <a href="https://drafts.fxtf.org/filters/publish/Filters.html">Filter Effects</a>
    specification does not define the <code>feCustom</code> element. This document proposes the following
    definition.</p>
    
    <div class="element-summary">
        <div class="element-summary-name">
            <span class="element-name">‘feCustom’</span>
        </div>
        <dl>
            <dt>Content model:</dt>
            <dd>Any number of the following elements, in any order:
                    <ul class="no-bullets">
                        <li><a href="https://www.w3.org/TR/2003/REC-SVG11-20030114/animate.html#AnimateElement"><span class="element-name">‘animate’</span></a></li>
                        <li><a href="https://www.w3.org/TR/2003/REC-SVG11-20030114/animate.html#SetElement"><span class="element-name">‘set’</span></a></li>
                    </ul>
            </dd>
            <dt>Attributes:</dt>
            <dd>
                <ul class="no-bullets">
                    <li><a href="https://www.w3.org/TR/2003/REC-SVG11-20030114/intro.html#TermCoreAttributes">core attributes</a></li>
                    <li><a href="https://www.w3.org/TR/2003/REC-SVG11-20030114/intro.html#TermPresentationAttribute">presentation attributes</a></li>
                    <li><a href="https://www.w3.org/TR/2003/REC-SVG11-20030114/intro.html#TermFilterPrimitiveAttributes">filter primitive attributes</a></li>
                    <li><a href="https://www.w3.org/TR/SVG/styling.html#ClassAttribute"><span class="attr-name">‘class’</span></a></li>
                    <li><a href="https://www.w3.org/TR/SVG/styling.html#StyleAttribute"><span class="attr-name">‘style’</span></a></li>
                    <li><a href="#feCustomVertexShaderAttribute"><span class="attr-name">‘vertexShader’</span></a></li>
                    <li><a href="#feCustomFragmentShaderAttribute"><span class="attr-name">‘fragmentShader’</span></a></li>
                    <li><a href="#feCustomVertexMeshAttribute"><span class="attr-name">‘vertexMesh’</span></a></li>
                    <li><a href="#feCustomParams"><span class="attr-name">‘params’</span></a></li>
                </ul>
            </dd>
        </dl>
    </div>
    
    <div>
        <dl>
            <dt id="feCustomVertexShaderAttribute">vertexShader: <code>&lt;uri&gt;</code></dt>
            <dd>The shader at &lt;uri&gt; provides the implementation for the <code>feCustom</code>
                vertex shader. If the 
                shader cannot be retrieved, or if the shader cannot be loaded or compiled because it contains erroneous code, the shader is a <a href="#default-shaders">pass through</a>. Otherwise, the vertex shader is invoked for all the vertex mesh vertices. 
                </dd>
        </dl>
        <dl>
            <dt id="feCustomFragmentShaderAttribute">fragmentShader: <code>&lt;uri&gt;</code></dt>
            <dd>The shader at &lt;uri&gt; provides the implementation for the <code>feCustom</code>
                fragment shader. If the 
                shader cannot be retrieved, or if the shader cannot be loaded or compiled because it contains erroneous code,  the shader is a <a href="#default-shaders">pass through</a>. Otherwise, the fragment shader
                is invoked for each of the pixels during the rasterization phase that follows
                the vertex shader processing.
                </dd>
        </dl>
        <dl>
            <dt id="feCustomVertexMeshAttribute">vertexMesh: <code>+&lt;integer&gt;{1,2}[wsp&lt;box&gt;][wsp'detached']</code></dt>
            <dd>See the <a href='#vertexMesh-attribute'>vertexMesh</a> attribute discussion</dd>
        </dl>
        <dl>
            <dt id="feCustomParamsAttribute">params: <code>[&lt;param-def&gt;[,&lt;param-def&gt;*]]</code></dt>
            <dd>
                Parameters are passed as uniforms to both the vertex and the fragment shaders.
                <table class="values-desc">
                    <tr>
                        <td id="param-def">&lt;param-def&gt;</td>
                        <td> &lt;param-name&gt;wsp&lt;param-value&gt;</td>
                    </tr>
                    <tr>
                        <td>&lt;param-name&gt;</td>
                        <td>&lt;ident&gt;</td>
                    </tr>
                    <tr>
                        <td>&lt;param-value&gt;</td>
                        <td>true|false[wsp+true|false]{0-3} | <br />
                            &lt;number&gt;[wsp+&lt;number&gt;]{0-3} | <br/>
                            &lt;array&gt; | <br />
                            &lt;transform&gt; | <br />
                            &lt;texture(&lt;uri&gt;)&gt;</td>
                    </tr>
                    <tr>
                        <td>&lt;array&gt;</td>
                        <td>'array('&lt;number&gt;[wsp&lt;number&gt;]*')'</td>
                    </tr>
                    <tr>
                        <td>&lt;transform&gt;</td>
                        <td>&lt;css-3d-transform&gt; | &lt;mat&gt;</td>
                    </tr>
                    <tr>
                        <td>&lt;css-3d-transform&gt;</td>
                        <td><a href="https://www.w3.org/TR/css3-3d-transforms/#transform-functions">&lt;transform-function&gt</a>;[&lt;transform-function&gt;]*
                    </tr>
                    <tr>
                        <td>&lt;mat&gt;</td>
                        <td>'mat2('&lt;number&gt;(,&lt;number&gt;){3}')' |  <br/>
                            'mat3('&lt;number&gt;(,&lt;number&gt;){8}')' |  <br/>        
                            'mat4('&lt;number&gt;(,&lt;number&gt;){15}')'
                        )</td>
                    </tr>
                    <tr></tr>
                </table>
                
                <p>There are two ways to specify a 4x4 matrix. They differ in 
                    <a href="#integration-with-css-animations-transitions">how 
                    they are interpolated.</a></p>

                <p>The <code>&lt;mat&gt;</code> values are in column major order.
                    For example, <code>mat2(1, 2, 3, 4)</code> has <code>[1, 2]</code> in the
                    first column and <code>[3, 4]</code> in the second one.</p>
            </dd>
        </dl>
    </div>
    
    <div class="note">There may be different ways to specify the &lt;param-value&gt; syntax. For example, it
        might be better to not have a <code>texture()</code> function and simply a &lt;uri&gt; for texture
        parameters. Or it might be better to not have a <code>mat&lt;n&gt;</code> prefixes for matrices.</div>
    
    <div class="note">
        <p>The following <a href="https://developer.mozilla.org/en/WebGL/Adding_2D_content_to_a_WebGL_context">document</a> from Mozilla
        describes how WebGL vertex and fragment shaders can be defined in <code>&lt;script&gt;</code> elements.</p>
            
        <p>CSS shaders can reference shaders defined in <code>&lt;script&gt;</code> elements, as shown in the 
        following code snippet.</p>
    
        <div><code class="xml"><pre>
&lt;script id="warp" type="x-shader/x-vertex" &gt;
&lt;-- source code here --&gt;
&lt;/script&gt;

..
&lt;style&gt;
.shaded {
    filter: custom(url(#warp));
}</pre></code>
        </div>
    </div>
    <h4 id="vertexMesh-attribute">The 'vertexMesh' attribute</h4>

    <p>The <code>&lt;feCustom&gt;</code>'s 'vertexMesh' attribute defines the granularity of vertices in
        the <a href="#vertex-mesh">shader mesh</a>. By default,
        the vertex mesh is made of two triangles that encompass the <a href="#filter-region">filter region</a> area.</p>

    <dl>
        <dt><code>+&lt;integer&gt;{1,2}[wsp&lt;box&gt;][wsp'detached']</code></dt>
        <dd>
            One or two positive integers (zero is invalid) indicating the additional number 
            of vertex lines and columns that will make the vertex
            mesh. With the initial value of '1 1' there is a single line and a single column, resulting in 
            a four-vertices mesh (top-left, top-right, bottom-right, bottom-left). If only one value is specified, the
            second (columns) value computes to the first value. In other words, a value of 'n' is equivalent to a 
            value of 'n n'.<br />
            A value of 'n m' results in a vertex mesh that has 'n' lines and 'm' column and a total of 
            'n + 1'.'m + 1' vertices as illustrated in the following figure.
            
            <p>The optional &lt;box&gt; parameter defines the box on which the vertex mesh is stretched to.
            It defaults to the 'filter-box' value which is 'border-box' with the added filter margins. 
            For elements that do not have padding or borders (e.g., SVG elements), the values 'padding-box'
            and 'border-box' are equivalent to 'content-box'. For SVG elements, the 'content-box' is 
            the object bounding box.</p>
            
            <p>The optional 'detached' string specifies whether the mesh triangles are attached or detached.
            If the value is not specified, the triangles are attached. If 'detached' is specified, the 
            triangles are detached. When triangles are attached, the geometry provided to the vertex shader
            is made of a triangles which share adjacent edges' vertices. In the 'detached'
            mode, the triangles do not share edges.</p>
            
            <p>In the following figure, let us consider the top-left 'tile' in the shader mesh.
                In the detached mode, the vertex shader will receive the bottom right and top left 
                vertices multiple time, one of each of the two triangles which make up the tile.
                Otherwise, the shader will receive these vertices only once, because they are 
                shared by the 'connected' triangles.</p>
                
            <p>See the discussion on uniforms passed to shaders to 
            understand how the shader programs can leverage that feature.</p>
            </dd>
    </dl>

    <div class="figure">
        <img src="images/shader-mesh-property.png" width="300" />
        <p class="caption">vertexMesh: 6 5</p>
    </div>

    <p>The above figure illustrates how a 'vertexMesh' value of '5 4' adds vertices passed to the vertex shader.
        The red vertices are the default ones and the gray vertices are resulting from the 'vertexMesh' value.</p>

    <div class="example">
        <p>The following example applies a vertex shader ('distort.vs') to elements with class 'distorted'.
            The vertex shader will operate on a mesh that has 5 lines and 4 columns (because there are 4 additional
            lines and 3 additional columns).</p>

        <code class="idl"><pre>
    &lt;style&gt;
    .distorted {
        filter: custom(url(distort.vs), 4 3);
    }
    &lt;/style&gt;

    ...
    &lt;div class="distorted"&gt;
    ..
    &lt;/div&gt;</pre></code>
        
which could also be written as:

    <code class="idl"><pre>
&lt;style&gt;
.distorted {
    filter: url(#distort);
}
&lt;/style&gt;

...

&lt;filter id="distort"&gt;
    &lt;feCustom vertexShader="url(distort.vs)" vertexMesh="4 3" /&gt;
&lt;/filter&gt;

&lt;div class="distorted"&gt;
..
&lt;/div&gt;</pre></code>
    </div>
    
<h3 id="shader-inputs">Shader inputs in filter graph</h3>

<p>When an <code>feCustom</code> filter primitive is used in a filter graph, a 'texture' parameter 
    can take a value of 'result(&lt;name&gt;)' where 'name' is the output of another filter primitive.</p>
    
<code class="idl"><pre>
&lt;filter&gt;
    &lt;feGaussianBlur stdDeviation="8" result="blur" /&gt;
    &lt;feTurbulence type="fractalNoise" baseFrequency="0.4" numOctaves="4" result="turbulence"/&gt;
    &lt;feCustom fragmentShader="url(complex.fs)" params="tex1 result(blur), tex2 result(turbulence)" /&gt;
&lt;/filter&gt;</pre></code>

<h2 id="properties">Properties</h2>

<div class="note">
    <p>There are <a href="http://lists.w3.org/Archives/Public/public-fx/2011JulSep/0093.html">current 
        discussions</a> in the FX task force about computing filter regions automatically.
    CSS shaders add a new requirement to that discussion, because it may be non-trivial to compute
    the filter region of a custom filter automatically.</p>
    
    <p>The ideal solution, from an authoring perspective, is to define how to compute 
        filter regions automatically to create the desired effect in all cases, including custom 
        filters. The proposed filter margin properties, specified below, would not be required if
        a solution to the automatic computation of filter region is found and agreed upon.</p>
</div>

<h3 id="filter-margin-property">Filter margins properties: 'filter-margin-top', 'filter-margin-bottom', 'filter-margin-left', 'filter-margin-right', and 'filter-margin'</h3>

<p>The 'filter-margin' properties define the <a href="https://drafts.fxtf.org/filters/publish/Filters.html#FilterEffectsRegion">filter effect region</a> for filters defined with filter functions such as the 'custom()' function defined in this document. If the filter property references a <code>&lt;filter&gt;</code> element, then the filter effect region defined by the element takes precedence over the 'filter-margin' property.</p>
    
<p>On a regular <code>&lt;filter&gt;</code> element, the x, y, width and height attributes define the <a href="https://drafts.fxtf.org/filters/publish/Filters.html#FilterEffectsRegion">filter effects region</a>.</p>
    
<p>The following sections describe the 'filter-margin-top', 'filter-margin-left', 'filter-margin-bottom', 'filter-margin-right' properties.</p>

<p>The filter-margin properties are a shorthand mechanism for defining a filter region equivalent to:</p>

<code class="xml"><pre>
&lt;filter filterUnits="objectBoundingBox" 
        x="fx(targetBox, [filter-margin-left])"
        y="fy(targetBox, [filter-margin-top])"
        width="fw(targetBox, [filter-margin-left], [filter-margin-right])"
        height="fh(targetBox, [filter-margin-top], [filter-margin-bottom])"&gt;
    &lt;!-- filter primitives for the filter function --&gt;
&lt;/filter&gt;
</pre></code>

<p>Where:</p>

<ul>
    <li><code id="targetBox">targetBox = borderBox | objectBoundingBox</code>
    <li><code>borderBox</code> is the element's generated <a href="https://www.w3.org/TR/CSS2/box.html#box-dimensions">border box</a> dimensions for elements subject to 
        CSS Visual Formatting, such as HTML elements (see [[!CSS21]]).</code></li>
    <li><code>objectBoundingBox</code> is the element's <a href="https://www.w3.org/TR/SVG/coords.html#ObjectBoundingBoxUnits">object bounding box</a>.</code></li>
    <li><code>fx(box, left) = - (left / box.width)</code></li>
    <li><code>fy(box, top) = - (top / box.height)</code></li>
    <li><code>fw(box, left, right) = ((box.width + left + right) / box.width)</code></li>
    <li><code>fh(box, top, bottom) = ((box.height + top + bottom) / box.height)</code></li> 
</ul>

<p>Margin properties specify the width of the <span>filter region</span> of a box. The ’filter-margin’ shorthand property sets the margin for all four sides while the other margin properties only set their respective side. These properties apply to all elements (which is different from the regular margin
    properties where vertical margins will not have any effect on non-replaced inline elements).</p>
    
<p>The 'filter-margin-top', 'filter-margin-bottom', 'filter-margin-left', 'filter-margin-right' can
    take the same values are the 'margin-top', 'margin-bottom', 'margin-left' and 'margin-right' 
    properties, respectively. In addition, they can take the 'auto' value which is also their default value.</p>
    
<p>The 'filter-margin' property can take the same values as the 'margin' property and is a shorthand
    for setting 'filter-margin-top', 'filter-margin-right', 'filter-margin-bottom' and 
    'filter-margin-left' at the same place in the stylesheet.</p>
    
<p>The following figure illustrates how the various filter-margin properties affect the filter region.</p>

<div class="figure">
    <img src="images/filter-region.png" width="300" />
    <p class="caption">The filter region</p>
</div>

<p>The blue border delimit the filter region. The margins are represented by:</p>

<ul>
    <li>A: filter-margin-left</li>
    <li>B: filter-margin-right</li>
    <li>C: filter-margin-top</li>
    <li>D: filter-margin-bottom</li>
</ul>


    <table class=propdef>
      <tr>
        <th>Name:
        <td><dfn>filter-margin-top, filter-margin-right, filter-margin-bottom, filter-margin-left</dfn>
      <tr>
        <th>Value:</th>
        <td><code>&lt;margin-width&gt; | inherit | auto</code></td>
      <tr>
        <th>Initial</th>
        <td>auto</td>
      <tr>
        <th>Applies to:</th>
        <td>all elements</td>
      <tr>
        <th>Inherited:
        <td>no
      <tr>
        <th>Percentages:
        <td>refer to the containing block
      <tr>
        <th>Media:
        <td>visual
      <tr>
        <th>Computed&nbsp;value:
        <td>the percentage as specified or the absolute length. A value of auto computes to 10% of the targetBox</td>
    </table>

  <h2 id="integration-with-css-animations-transitions">Integration with CSS Animations and CSS Transitions</h2>

  <p>The attributes and properties defined in this document can be subject to animation as any other
      attribute or CSS property.</p>
      
  <p>Even though the Filter Effects specification does not clarify that point, this document assumes that
      the 'filter' property can be animated and that interpolation happens between the filter functions 
      only if the 'filter' values have the same number of filter functions appearing in the same order.</p>

  <h3 id="shader-params-interpolation">Interpolating the shader-params component in the custom() function.</h3>

  <p>To interpolate between <a href="#shader-params"><code>params</code></a> values in a
      <code>custom()</code> filter function or between 
      <code>&lt;feCustom&gt;</code>
      <a href="#feCustomParamsAttribute">'params'</a> attribute values, the user
      agent should interpolate between each of the <strong><a href="#param-def">[param-def]</a></strong> values
      according to its type. List of values need to be of the same length. Matrices need to be of the same
      dimension. Arrays need to be of the same size.</p>
      
  <p class="note">
    Interpolation between shader params only happens if all the other shader properties are identical:
    vertex shader, fragment shader, filter margins and vertex mesh.
  </p>

  <table class="values-desc">
      <tr>
          <td><code>&lt;number&gt;[wsp&lt;number&gt;{0-3}]</code></td>
          <td>Interpolate between each of the values.</td>
      </tr>
      <tr>
          <td><code>&lt;true|false&gt;[wsp&lt;true|fals&gt;{0-3}]</code></td>
          <td>Interpolate between each of the values using a step function.</td>
      </tr>
      <tr>
          <td><code>&lt;array&gt;</code></td>
          <td>Interpolate between the array elements.</td>
      </tr>
      <tr>
          <td><code>&lt;css-3d-transform&gt;</code></td>
          <td>Follows the <a href="https://www.w3.org/TR/css3-3d-transforms/#animation">CSS 3D transform interpolation rules</a>.</td>
      </tr>
      <tr>
          <td><code>&lt;mat&gt;</code></td>
          <td>Interpolate between the matrix components (applies to mat2, mat3 and mat4).</td>
      </tr>
  </table>

  <div class="note">
      As with the 'transform' property, it is not possible to animate the different components of the 
      'shader-params' property on different timelines or with different keyframes. This is a generic
      issue of animating properties that have multiple components to them.
  </div>

<h2 id="shading-language">Shading language</h2>

<h3 id="precedents">Precedents</h3>

<p>There are many precedents for shading languages, for example:</p>
<ul>
    <li><a href="http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf">OpenGL ES Shading Language</a> (also known as GLSL ES) from <a href="http://www.khronos.org/registry/webgl/specs/latest/#refsGLES20GLSL">WebGL</a></li>
    <li><a href="http://msdn.microsoft.com/en-us/library/bb509635(v=VS.85).aspx">HLSL Shading Language</a></li>
    <li><a href="http://www.adobe.com/content/dam/Adobe/en/devnet/pixelbender/pdfs/pixelbender_reference.pdf">Adobe's Pixel Bender language</a></li>
    <li><a href="http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/CoreImaging/ci_custom_filters/ci_custom_filters.html%23//apple_ref/doc/uid/TP30001185-CH207-TPXREF101">Apple's CoreImage Filters</a></li>
</ul>

<h3 id="recommendation">Recommended shading language</h3>

<p>This document recommends the adoption of the subset of <a href="http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf">GLSL ES</a> defined in the <a href="http://www.khronos.org/registry/webgl/specs/1.0/">WebGL 1.0</a> specification.</p>
    
    <p>In particular, the same restrictions as defined in WebGL should apply to CSS shaders:</p>
    
    <ul>
        <li><a href="http://www.khronos.org/registry/webgl/specs/latest/#SUPPORTED_GLSL_CONSTRUCTS">supported GLSL constructs.</a></li>
        <li><a href="http://www.khronos.org/registry/webgl/specs/latest/#6">differences between WebGL and OpenGL ES 2.0</a> as it applies to shaders.</li>
    </ul>
 
    <p>All the parameters specified in the <code>&lt;shader-params&gt;</code> values (e.g., the <code>feCustom's param</code> attribute or the <code>custom(&lt;uri&gt;, &lt;shader-params&gt;)</code> filter function or the <code>shader</code> property value) will be available as uniforms to the shader(s) referenced by the 'shader' property.</p>
   
<p>The group may consider applying further restrictions to the GLSL ES language to make it easier to 
    write vertex and fragment shaders.</p>
    
<p>The OpenGL ES shading language provides a number of variables that can be passed to shaders,
    exchanged between shaders or set by shaders. In particular, a vertex shader can provide specific
    data to the fragment shader in the form of 'varying' parameters (parameters that vary per pixel).
    The following sections describe particular variables that are assumed for the 
    vertex and fragment shaders in CSS shaders.</p>
    
<div class="note">
    Even though this document recommends the GLSL ES shading language, there are other possible options to 
    consider, for example:
    <ul>
        <li>Allow multiple shading languages, present or future (similar to how the &lt;script&gt; tag 
            allows different scripting languages).</li>
        <li>Define a shading language specific to custom filter effects.</li>
    </ul>
    
    The implementation could use the mime type of the url or &lt;script&gt; element
    to determine the the shading language.
</div>
    
<h4>Vertex attribute variables</h4>

The following attribute variables are available to the vertex shader.

<table class="values-desc">
    <tr>
        <td><code>attribute vec4 a_position</code></td>
        <td>The vertex coordinates in the <a href="#filter-region">filter region</a> box. 
            Coordinates are normalized to the [-0.5, 0.5] range along the x, y and z axis.</td>
    </tr>
    <tr>
        <td><code>attribute vec2 a_texCoord;</code></td>
        <td>The vertex's texture coordinate. Coordinates are in the [0, 1] range on both axis</td>
    </tr>
    <tr>
        <td><code>attribute vec2 a_meshCoord;</code></td>
        <td>The vertex's coordinate in the <a href="#mesh-box">mesh box</a>. 
            Coordinates are in the [0, 1] range on both axis.</td>
    </tr>
    <tr>
        <td><code>attribute vec3 a_triangleCoord;</code></td>
        <td><p>The x and y values provide the coordinate of the current 'tile' in the shader mesh. 
            For example, (0, 0) for the
            top right tile in the mesh. The x and y values are in the [0, mesh columns] and [0, mesh rows]
            range, respectively.</p>
            <p>The z coordinate is computed according to the following figure. The z coordinate value 
                is provided for each vertex and corresponding triangle. For example, for the bottom
                right vertex of the top triangle, the z coordinate will be 2. For the bottom
                right vertex of the bottom triangle, the z coordinate will be 4.</p>
    </tr>
    </tr>
    
</table>

            
            <div class="figure">
            <img src="images/a_triangleCoord.z.png" width="50%"/>
            <p class="caption">The a_triangleCoord.z value</p>
            </div>
            </td>

<h4>Shader uniform variables</h4>

The following uniform variables are set to specific values by the user agent:

<table class="values-desc">
    <tr>
        <td><code>uniform mat4 u_projectionMatrix</code></td>
        <td>The current projection matrix to the 
            destination texture's coordinate space). <em>Note that the 'model matrix' which 
            the 'transform' property sets, is not passed to the shaders. It is applied to the 
            filtered element's rendering.</em></td>
    </tr>
    <tr>
        <td><code>uniform sampler2D u_texture</code></td>
        <td>The input texture. Includes transparent margins for the filter margins.</td>
    </tr>
    <tr>
        <td><code>uniform sampler2D u_contentTexture</code></td>
        <td>A texture with the rendering of the filtered element. If the filter is the first
            in the filter chain, then, this texture is the same as the u_texture uniform. However,
            if there are preceding filters, this provides the rendering of the original filtered element,
            whereas u_texture provides the output of the preceding filter in the filter chain (or graph).</td>
    </tr>
    <tr>
        <td><code>uniform vec2 u_textureSize</code></td>
        <td>The input texture's size. Includes the filter margins.</td>
    </tr>
    <tr>
        <td><code>uniform vec4 u_meshBox</code></td>
        <td>The mesh box position and size in the <a href="#filter-box">filter box</a> coordinate
            system. For example, if the mesh box is the filter box, the value will be (-0.5, -0.5, 1, 1).</td>
    </tr>
    <tr>
        <td><code>uniform vec2 u_tileSize</code></td>
        <td>The size of the current mesh tile, in the same coordinate space as the vertices.</td>
    </tr>
    <tr>
        <td><code>uniform vec2 u_meshSize</code></td>
        <td>The size of the current mesh in terms of tiles. The x coordinate provides the number of
            columns and the y coordinate provides the number of rows.</td>
    </tr>
</table>

<h4>Varyings</h4>

<p>When the author provides both a vertex and a fragment shader, there is no requirement on the 
    varyings passed from the vertex shader to the fragment shader. If no vertex shader is provided,
    the fragment shader can expect the <code>v_texCoord</code> varying. If no fragment shader is 
    provided, the vertex shader must compute a v_texCoord varying for the default shaders.</p>
    
<table class="values-desc">
<tr>
    <td>varying vec2 v_texCoord;</td>
    <td>The current pixel's texture coordinates (in u_texture).</td>
</tr>
</table>

<h4>Other uniform variables: the CSS shaders parameters</h4>

<p>When there parameters are passed to the <code>custom()</code> filter function or the 
    <code>feCustom</code> filter primitive, the user agent pass uniforms of the corresponding name and
    type to the shaders.</p>
    
<p>The following table shows the mapping between CSS shader parameters and uniform types.</p>

    <div class="table">
<table class="values-desc">
    <tr>
        <th>CSS param type</th>
        <th>GLSL uniform type</th>
    </tr>
    <tr>
        <td>true|false[wsp+true|false]{0-3}</td>
        <td>bool, bvec2, bvec3 or bvec4</td>
    </tr>
    <tr>
        <td>&lt;number&gt;[wsp+&lt;number&gt;]{0-3}
        <td>float, vec2, vec3 or vec4</td>
    </tr>
    <tr>
        <td>
            &lt;array&gt;
        </td>
        <td>
            float[n]
        </td>
    </tr>
    <tr>
        <td>
            &lt;css-3d-transform&gt;
        </td>
        <td>
            mat4
        </td>
    </tr>
    <tr>
        <td>'mat2('&lt;number&gt;(,&lt;number&gt;){3}')' | <br />
            'mat3('&lt;number&gt;(,&lt;number&gt;){8}')' | <br />    
            'mat4('&lt;number&gt;(,&lt;number&gt;){15}')'</td>
        <td>
            mat2, mat3 or mat4
        </td>
    </tr>
    <tr>
        <td>texture(&lt;uri&gt;)</td>
        <td>sampler2D</td>
    </tr>
</table>
</div>

    <p>The following code sample illustrates that mechanism.</p>
    
<div class="example">
    <code><pre>
<strong>CSS</strong>

.shaded {
    filter: custom(
                   url(distort.vs) url(tint.fs), 
                   distortAmount 0.5, lightVector 1.0 1.0 0.0, 
                   disp texture(disp.png)
                );
}

<strong>Shader (vertex or fragment)</strong>
...

uniform float distortAmount;
uniform vec3 lightVector;
uniform sampler2D disp;
uniform vec2 dispSize;
...</pre></code>
</div>

<p>As illustrated in the example, for each <code>&lt;textureName&gt; texture()</code> parameter, an additional <code>vec2</code> uniform is passed 
    to the shaders with the size of the corresponding texture.
    

<h4>Default shaders</h4>

<p>If no vertex shader is provided, the default one is as shown below.</p>

<div id="default-vertex-shader" class="shader example">
    <code class="idl"><pre>
attribute vec4 a_position;
attribute vec2 a_texCoord;

uniform mat4 u_projectionMatrix;

varying vec2 v_texCoord;

void main()
{        
    v_texCoord = a_texCoord;
    gl_Position = u_projectionMatrix * a_position;
}

    </pre></code>
</div>

<p>If no fragment shader is provided, the default one is shown below.</p>

<div id="default-fragment-shader" class="shader example">
        <code class="idl"><pre>
varying vec2 v_texCoord;
uniform sampler2D u_texture;

void main()
{  
    gl_FragColor = texture2D(u_texture, v_texCoord);  
}        </pre></code>
</div>

<h4>Texture access</h4>

<p>If shaders access texture values outside the <code>[0, 1]</code> range on both axis, the
    returned value is a fully transluscent black pixel.</p>

<h3 id="security-considerations">Security considerations</h3>

<p>Since vertex and fragment shaders are programs that would be executed by the user agent, it is important
    to consider the security implications.</p>
    
<p>The same <a href="http://www.khronos.org/webgl/security/">efforts</a> made on making
    WebGL highly secure would apply to CSS shaders, since this document proposes to share the same shading 
    language.</p>
    
<p>In addition, CSS shaders offer a restricted environment for shaders. Scripts have no access to the shaders output
    and no communication is possible between the shaders and the page's scripts or external servers. Possible denial 
    of service attack are a concern. There are active efforts
    to address these issues for WebGL and these efforts would apply to CSS shaders.</p>
    
<p>In addition, the group may consider adding restrictions on the number of parameters allowed for shaders,
    as well as the size of input textures, vertex mesh size and number of shader parameters.</p>
    

<p>The working group should decide on restrictions that will apply to shaders, to avoid information leakage. <a href="http://www.contextis.com/resources/blog/webgl/">Timing attack</a> are an example of a method to compute the content pixel values without having actual API access to the pixel values. However, it seems difficult to mount such an attack with CSS shaders because the means to measure the time taken by a cross-domain shader are limited.</p>
    
<p>The group could decide to limit the cross domain usage of shaders or shader textures, and only
    permit the use of same domain shaders and textures or only allow those validated through
    <a href="https://www.w3.org/TR/cors/">Cross Origin Resource Sharing</a>.</p>


<h2 class=no-num id=acknowledgments>Acknowledgments</h2>

  <p>Many thanks to Mihnea Vlad-Ovidenie, Alexandru Chiculita and Andrei Valentin Onea for their 
      help defining and prototyping the features proposed in this note. Thanks to Ken Russell for his
      input and discussion about WebGL. Thanks to Benoit Jacob and Robert O&#146;Callahan for the discussion
      on security, parameter typing and filter margins and some WebGL precedents.</p>

  <p>Thanks to Ben Schwarz and Jerrold Maddox for their guidance creating a legible design for this
      specification proposal. Any remaining design errors would be the editor&#146;s failure to follow their
      recommendations.</p>
      
<h2 class=no-num id=change-log>Change Log</h2>

<h3>October 19 2011</h3>

<ul>
    <li>Added 'detached' mode proposal for shader mesh.</li>
    <li>Added new uniforms: u_contentTexture, u_tileSize, u_tilePos, u_meshSize</li>
    <li>Added new attribute: a_triangleCoord.</li> 
    <li><a href="http://www.w3.org/Graphics/fx/wiki/Custom_Filters#Issue_01">Issue 01</a>: changed shaderMesh to be the number of lines and columns instead of the number of 
        additional lines and columns.</li>
    <li><a href="http://www.w3.org/Graphics/fx/wiki/Custom_Filters#Issue_03">Issue 03</a>: added a 
        <a href='#about_interactivity'>note</a> at the end of the model section.</li>
    <li><a href="http://lists.w3.org/Archives/Public/www-style/2011Oct/0186.html">Feedback from Chris Marrin</a>: 
        added references to WebGL restrictions.</li>
    <li>Renamed s_texture to u_texture for consistency, since uniforms are prefixed with 'u_'</li>
</ul>
<h2 class=no-num id=references>References</h2>


<h3 class="no-num" id="normative-references">Normative references</h3>
<!--normative-->

<h3 class="no-num" id="other-references">Other references</h3>
<!--informative-->

<h2 class="no-num" id="index">Index</h2>
<!--index-->


<h2 class="no-num" id="property-index">Property index</h2>
<!-- properties -->
</body>
</html>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-declaration:"~/SGML/HTML4.decl"
sgml-default-doctype-name:"html"
sgml-minimize-attributes:t
sgml-nofill-elements:("pre" "style" "br")
sgml-live-element-indicator:t
sgml-omittag:nil
sgml-shorttag:nil
sgml-namecase-general:t
sgml-general-insert-case:lower
sgml-always-quote-attributes:t
sgml-indent-step:nil
sgml-indent-data:t
sgml-parent-document:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
 
